import { Injectable, Logger } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { firstValueFrom } from 'rxjs';
import { OpenRouterCompletionRequestDto } from '../dto/openrouter/completion-request.dto';
import { OpenRouterChatCompletionRequestDto } from '../dto/openrouter/chat-completion-request.dto';
import {
  TextCompletionResponseDto,
  ChatCompletionResponseDto,
} from '../dto/completion-response.dto';

@Injectable()
export class OpenRouterService {
  private readonly logger = new Logger(OpenRouterService.name);
  private readonly apiUrl = 'https://openrouter.ai/api/v1';
  private readonly defaultModel = 'mistralai/mixtral-8x7b-instruct';

  constructor(
    private configService: ConfigService,
    private httpService: HttpService,
  ) {}

  /**
   * 获取API密钥
   * @returns API密钥字符串
   * @throws 如果API密钥未设置
   */
  private getApiKey(): string {
    const apiKey =
      this.configService.get<string>('OPENROUTER_API_KEY') ||
      this.configService.get<string>('ai.openrouter.apiKey');
    if (!apiKey) {
      throw new Error('OpenRouter API key is not set');
    }
    return apiKey;
  }

  /**
   * 生成文本完成
   * @param request 完成请求
   * @returns 生成的文本完成响应
   */
  async generateCompletion(
    request: OpenRouterCompletionRequestDto,
  ): Promise<TextCompletionResponseDto> {
    try {
      const apiKey = this.getApiKey();

      // 设置默认值
      const model = request.model || this.defaultModel;
      const maxTokens = request.max_tokens || 1024;

      // 准备请求参数
      const requestData = {
        model,
        prompt: request.prompt,
        max_tokens: maxTokens,
        temperature: request.temperature,
        top_p: request.top_p,
        top_k: request.top_k,
        frequency_penalty: request.frequency_penalty,
        presence_penalty: request.presence_penalty,
        repetition_penalty: request.repetition_penalty,
        seed: request.seed,
        logit_bias: request.logit_bias,
        top_logprobs: request.top_logprobs,
        min_p: request.min_p,
        top_a: request.top_a,
        transforms: request.transforms,
        models: request.models,
        route: request.route,
        provider: request.provider,
        reasoning: request.reasoning,
      };

      // 发送请求
      const response = await firstValueFrom(
        this.httpService.post(`${this.apiUrl}/completions`, requestData, {
          headers: {
            Authorization: `Bearer ${apiKey}`,
            'Content-Type': 'application/json',
          },
        }),
      );

      // 解析响应
      const data = response.data;
      const choices = data.choices || [];
      const text = choices.length > 0 ? choices[0].text : '';

      // 构建响应
      return {
        model: data.model || model,
        text,
        rawResponse: data,
      };
    } catch (error) {
      this.logger.error(
        `Error generating completion: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw error;
    }
  }

  /**
   * 生成聊天完成
   * @param request 聊天完成请求
   * @returns 生成的聊天完成响应
   */
  async generateChatCompletion(
    request: OpenRouterChatCompletionRequestDto,
  ): Promise<ChatCompletionResponseDto> {
    try {
      const apiKey = this.getApiKey();

      // 设置默认值
      const model = request.model || this.defaultModel;
      const maxTokens = request.max_tokens || 1024;

      // 准备请求参数
      const requestData = {
        model,
        messages: request.messages,
        max_tokens: maxTokens,
        temperature: request.temperature,
        top_p: request.top_p,
        top_k: request.top_k,
        frequency_penalty: request.frequency_penalty,
        presence_penalty: request.presence_penalty,
        repetition_penalty: request.repetition_penalty,
        seed: request.seed,
        logit_bias: request.logit_bias,
        top_logprobs: request.top_logprobs,
        min_p: request.min_p,
        top_a: request.top_a,
        transforms: request.transforms,
        models: request.models,
        route: request.route,
        provider: request.provider,
        reasoning: request.reasoning,
      };

      this.logger.log(
        `Sending request to OpenRouter: ${JSON.stringify(requestData, null, 2)}`,
      );

      // 发送请求
      const response = await firstValueFrom(
        this.httpService.post(`${this.apiUrl}/chat/completions`, requestData, {
          headers: {
            Authorization: `Bearer ${apiKey}`,
            'Content-Type': 'application/json',
            'HTTP-Referer': 'https://nestjs-ai-tools.example.com',
            'X-Title': 'NestJS AI Tools',
          },
        }),
      );

      // 解析响应
      const data = response.data;
      const choices = data.choices || [];
      const message =
        choices.length > 0
          ? choices[0].message
          : { role: 'assistant', content: '' };

      // 构建响应
      return {
        model: data.model || model,
        message,
        rawResponse: data,
      };
    } catch (error) {
      this.logger.error(
        `Error generating chat completion: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw error;
    }
  }

  /**
   * 获取可用模型列表
   * @returns 可用模型的列表
   */
  async getModels() {
    try {
      const apiKey = this.getApiKey();

      const response = await firstValueFrom(
        this.httpService.get(`${this.apiUrl}/models`, {
          headers: {
            Authorization: `Bearer ${apiKey}`,
            'Content-Type': 'application/json',
          },
        }),
      );

      return response.data;
    } catch (error) {
      this.logger.error(
        `Error fetching models: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw error;
    }
  }

  /**
   * 获取用户的信用点数
   * @returns 用户的信用点数信息
   */
  async getCredits() {
    try {
      const apiKey = this.getApiKey();

      const response = await firstValueFrom(
        this.httpService.get(`${this.apiUrl}/credits`, {
          headers: {
            Authorization: `Bearer ${apiKey}`,
            'Content-Type': 'application/json',
          },
        }),
      );

      return response.data;
    } catch (error) {
      this.logger.error(
        `Error fetching credits: ${error instanceof Error ? error.message : String(error)}`,
        error instanceof Error ? error.stack : undefined,
      );
      throw error;
    }
  }
}
